#include "parser.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int checkHead(char * buff, int sizeBuff)
{
	char * ptrBuff = NULL;
	int retVal = INVALID_TYPE;
	if(sizeBuff<6)
	{
		return INVALID_TYPE;
	}
	if(buff[0] != '$')
	{
		return INVALID_TYPE;
	}
	else
	{
		ptrBuff = buff+3;
		if(0==strncmp(ptrBuff,"GGA",3))
		{
			retVal = GGA;
		}
		else if(0==strncmp(ptrBuff,"GLL",3))
		{
			retVal = GLL;
		}
		else if(0==strncmp(ptrBuff,"GSA",3))
		{
			retVal = GSA;
		}
		else if(0==strncmp(ptrBuff,"GSV",3))
		{
			retVal = GSV;
		}
		else if(0==strncmp(ptrBuff,"RMC",3))
		{
			retVal = RMC;
		}
		else if(0==strncmp(ptrBuff,"VTG",3))
		{
			retVal = VTG;
		}
		else if(0==strncmp(ptrBuff,"ZDA",3))
		{
			retVal = ZDA;
		}
	}	
	return retVal;     
}

void parseUtcTime(char * strIn, utcTime * pstUtcTime)
{
    //char * ptrMs = NULL;
	int hh = 0;
	int mm = 0;
	int ss = 0;
	int ms = 0;
	
	sscanf_s(strIn,"%2d%2d%2d.%3d",&hh,&mm,&ss,&ms);

	pstUtcTime->hh = (unsigned char)hh;
	pstUtcTime->mm = (unsigned char)mm;
	pstUtcTime->ss = (unsigned char)ss;
	pstUtcTime->ms = (unsigned char)ms;
}

int parseGGA(char * buff, int sizeBuff,ggaInfo * pstGgaOut)
{
	char strFieldsGGA[NUM_SUBSTR_GGA][20];	
	char buffBack[1024];
	char * buffStr = NULL;
	char *ptrSubStr = NULL;
	int i = 0;
	int count = 0;
	memcpy(buffBack,buff,sizeBuff);
	memset(strFieldsGGA,0,NUM_SUBSTR_GGA*20);
	
	/*ptrSubStr = strtok_s(buffBack + 7, ",", &buffStr);
	
	while(ptrSubStr)
	{
		strcpy_s(strFieldsGGA[i],ptrSubStr);
		if (buffStr[0] == ',')
		{
			i++;
		}
		ptrSubStr = strtok_s(NULL, ",", &buffStr);
		i++;
	}*/

	ptrSubStr = buffBack + 7;
	buffStr = ptrSubStr;
	count = 0;
	while (*buffStr != '\0')
	{
		while (*buffStr != ',')
		{
			buffStr++;			
			count++;
			if (*buffStr == '\0')
			{
				break;
			}
		}
		if (count)
		{
			memcpy(strFieldsGGA[i], ptrSubStr, count);
			count = 0;
		}
		i++;
		if (*buffStr == ',')
		{
			ptrSubStr = buffStr + 1;
		}
		else
		{
			ptrSubStr = buffStr;
		}
		buffStr = ptrSubStr;
	}

    parseUtcTime(strFieldsGGA[I_LOC_TIME], &pstGgaOut->stLoTime);
    pstGgaOut->fLatitude = atof(strFieldsGGA[I_LATITUDE]);
	pstGgaOut->enLatOrient = (strFieldsGGA[I_LATI_ORI][0] == 'N' || strFieldsGGA[I_LATI_ORI][0] == 'n')?North:South;
    pstGgaOut->fLongitude = atof(strFieldsGGA[I_LONGITUDE]);
	pstGgaOut->enLonOrient = (strFieldsGGA[I_LON_ORI][0] == 'E' || strFieldsGGA[I_LON_ORI][0] == 'e')?East:West;

    if(strFieldsGGA[I_STS_IN][0] == '1')
    {
        pstGgaOut->statusIndication = SPS_MODE;
    }
	else if(strFieldsGGA[I_STS_IN][0] == '6')
	{
	    pstGgaOut->statusIndication = ESTIMATE_MODE;
	}
	else
	{
	    pstGgaOut->statusIndication = LOC_INVALID;
	}

	pstGgaOut->numSatellites = atoi(strFieldsGGA[I_NUM_SATE]);
	pstGgaOut->fValHDOP = atof(strFieldsGGA[I_VAL_HDOP]);

    pstGgaOut->fHeightAntenna = atof(strFieldsGGA[I_HEIGHT_ANT]);
	pstGgaOut->fHeightException = atof(strFieldsGGA[I_HEIGHT_EXC]);
	pstGgaOut->iPeriodDiff = atoi(strFieldsGGA[I_PERIOD_DIFF]);
	pstGgaOut->fDiffPlatId = atof(strFieldsGGA[I_DIFF_ID]);
	return 0;
}

const char modeChars[MAX_MODE_NUM] = { 'A', 'D', 'E', 'M', 'N', 'S' };

int getModeIndex(char modeCharIn)
{
    int i=0;
    int retVal = INVALID_MODE;

	for (i = 0; i<MAX_MODE_NUM; i++)
	{
	    if(modeChars[i] == modeCharIn)
	    {
	       retVal = i;
	       break;
	    }
	}

	return retVal;
}


int parseVTG(char * buff, int sizeBuff,vtgInfo * pstVtgOut)
{
    char strFieldsVTG[NUM_SUBSTR_VTG][20];
	char * buffStr = NULL;
	char *ptrSubStr = NULL;
	int i = 0;
	int count = 0;

	memset(strFieldsVTG,0,NUM_SUBSTR_VTG*20);
    
	ptrSubStr = buff + 7;
	buffStr = ptrSubStr;
	count = 0;

	while (*buffStr != '\0')
	{
		while (*buffStr != ',')
		{
			buffStr++;			
			count++;
			if ((*buffStr == '\0')||(*buffStr == '*'))
			{
				break;
			}
		}
		if (count)
		{
			memcpy(strFieldsVTG[i], ptrSubStr, count);
			count = 0;
		}
		i++;
		if ((*buffStr == ',')||(*buffStr == '*'))
		{
			ptrSubStr = buffStr + 1;
		}
		else
		{
			ptrSubStr = buffStr;
		}
		buffStr = ptrSubStr;
	}

	pstVtgOut->fAzimuth = atof(strFieldsVTG[I_ORIENT_T]);	
	pstVtgOut->fAzimuth_m = atof(strFieldsVTG[I_ORIENT_M]);
	pstVtgOut->iIndicateNorth = (strFieldsVTG[I_INDICATE_T][0] == 'T')?1:0;
    pstVtgOut->iIndicateNorth_m = (strFieldsVTG[I_INDICATE_M][0] == 'M')?1:0;
	pstVtgOut->fSpeed_n = atof(strFieldsVTG[I_SPEED_N]);
	pstVtgOut->fSpeed_k = atof(strFieldsVTG[I_SPEED_K]);
	pstVtgOut->enLocationMode = getModeIndex(strFieldsVTG[I_LOC_MOD][0]);	

	return 0;	
}


